package cn.visu.security;

import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.filter.mgt.FilterChainManager;
import org.apache.shiro.web.filter.mgt.FilterChainResolver;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.mgt.WebSecurityManager;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.BeanInitializationException;

/**
 * 自定义 工厂
 */
public class MyShiroFilterFactoryBean extends ShiroFilterFactoryBean {

    private PathMatchingFilterChainResolver pathMatchingFilterChainResolver;

    @Override
    protected AbstractShiroFilter createInstance() throws Exception {


        SecurityManager securityManager = this.getSecurityManager();
        String msg;
        if (securityManager == null) {
            msg = "SecurityManager property must be set.";
            throw new BeanInitializationException(msg);
        } else if (!(securityManager instanceof WebSecurityManager)) {
            msg = "The security manager does not implement the WebSecurityManager interface.";
            throw new BeanInitializationException(msg);
        } else {

            //这一部分和源码不同 源码是只能有一种过滤器链  这里不同的人有不同的过滤器链
//            PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver();
//            chainResolver.setFilterChainManager(manager);
            return new MyShiroFilterFactoryBean.SpringShiroFilter((WebSecurityManager) securityManager, getPathMatchingFilterChainResolver());
        }
    }

    private static final class SpringShiroFilter extends AbstractShiroFilter {
        protected SpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) {
            if (webSecurityManager == null) {
                throw new IllegalArgumentException("WebSecurityManager property cannot be null.");
            } else {
                this.setSecurityManager(webSecurityManager);
                if (resolver != null) {
                    this.setFilterChainResolver(resolver);
                }

            }
        }
    }

    public PathMatchingFilterChainResolver getPathMatchingFilterChainResolver() {
        return pathMatchingFilterChainResolver;
    }

    public void setPathMatchingFilterChainResolver(PathMatchingFilterChainResolver pathMatchingFilterChainResolver) {
        this.pathMatchingFilterChainResolver = pathMatchingFilterChainResolver;
    }
}
